<?php

/*
 *	FalconKMS Parser
 *	Version 1.3
 * 	Author: Geoff Wilson (contact@gawilson.net)
 *
 *	The parser class is used to split up a killmail into its
 *	corresponding parts, once the killmail has been analyzed and
 *	validated, it is saved to the database using the Kill class
 *
 *	1.3
 *              * Added Faction support
 *      1.2
 *		* Fixed Revelations killmail posting
 *		* Fixed NPC's appearing in mails
 *	1.1
 *		* Simplified status codes, 1 = Worked, 0 = Failed
 *		* Re-wrote some of the way the mail is parsed, done in segments now
 *	1.0-BETA
 *		* Initial version
*/

require "killclass.php";

class Parser
{
	var $killmail;
	var $searchPosition;

	var $topSegment;
	var $middleSegment;
	var $bottomSegment;
	
	function Parser($mailText)
	{
		if (get_magic_quotes_gpc() == 0) $mailText = addslashes(stripslashes($mailText));

		// assign killmail to class variable
		$this->killmail = $mailText;

		// Reset search counter
		$this->searchPosition = 0;
	}

	/* Experimental Code */
	function newParser()
	{
	
		// Create a new instnace of a Kill to hold the new details
		$newMail = new Kill();
		$newMail->killmail = $this->killmail;
		
		// Break Kill Mail up into 3 sections
		$this->topSegment = explode("Involved parties:", $this->killmail);

		if (isset($this->topSegment[1]))
		{
			$this->middleSegment = explode("Destroyed items:", $this->topSegment[1]);
			$this->topSegment = $this->topSegment[0];
		}
		else 
		{
			logError("Parser > newParser() function", "Killmail is not in a valid format");
			return 0;
		}
		
		if (isset($this->middleSegment[1]))
		{
			$this->bottomSegment = $this->middleSegment[1];
		}
		
		$this->middleSegment = $this->middleSegment[0];
		
		/*
			VICTIM PARSING CODE
		*/
		$done = FALSE;
		$splitMail = explode("\r\n",$this->topSegment);
		
		// Find the date line
		while($done == FALSE)
		{
			$nextLine = substr($splitMail[$this->searchPosition],0,2);
			if ($nextLine == "20")
			{
				$timeStamp = explode(" ",$splitMail[$this->searchPosition]);
				$newMail->timestamp = strtotime(str_replace(".","-",$timeStamp[0]) . " " . $timeStamp[1]);

				// Make sure date isn't in the future (fake killmails etc..)
				if ($newMail->timestamp > time() + 1800)
				{
					logError("Parser > newParser() function", "Killmail was in the future");
					return 0;
				}

				$done = TRUE;
			}
			else if ($this->searchPosition == (count($splitMail) - 1))
			{
				logError("Parser > newParser() function", "Killmail has invalid victim header");
				return 0;
			}
			$this->searchPosition ++;			
		}
		
		
		$gotVictimName == FALSE;
		
		while ($gotVictimName == FALSE)
		{
			// Get the rest of the victim details
			$victimArray = explode(": ",$splitMail[$this->searchPosition]);
			if ($this->searchPosition == (count($splitMail) - 1))
			{
				logError("Parser > newParser() function", "Victims Name is not Found");
				return 0;
			}
			else if ($victimArray[0] == "Victim") 
			{
				$newMail->victim = $victimArray[1];
				$gotVictimName = TRUE;
			}
			$this->searchPosition++;		
		}
				
		$corpArray = explode(": ",$splitMail[$this->searchPosition]);
		if ($corpArray[0] == "Corp") 
		{
			$newMail->corp = $corpArray[1];
		}
		else 
		{
			logError("Parser > newParser() function", "Victims Corp is invalid");
			return 0;
		}
		$this->searchPosition++;

		$allianceArray = explode(": ",$splitMail[$this->searchPosition]);
		if ($allianceArray[0] == "Alliance") 
		{
			$newMail->alliance = $allianceArray[1];
		}
		else 
		{
			logError("Parser > newParser() function", "Victims Alliance is invalid");
			return 0;
		}
		$this->searchPosition++;

		$factionArray = explode(": ",$splitMail[$this->searchPosition]);
		if ($factionArray[0] == "Faction")
		{
			$newMail->faction = $factionArray[1];
		}
		else
		{
			logError("Parser > newParser() function", "Victims Faction is invalid");
			return 0;
		}
		$this->searchPosition++;
		
		$shipLostArray = explode(": ",$splitMail[$this->searchPosition]);
		if ($shipLostArray[0] == "Destroyed") 
		{
			$newMail->ship = $shipLostArray[1];
		}
		else 
		{
			logError("Parser > newParser() function", "Victims Ship is invalid");
			return 0;
		}
		$this->searchPosition++;
		
		$systemArray = explode(": ",$splitMail[$this->searchPosition]);
		if ($systemArray[0] == "System") 
		{
			$newMail->solarSystem = $systemArray[1];
		}
		else 
		{			
			logError("Parser > newParser() function", "System is invalid");
			return 0;
		}
		$this->searchPosition++;		
		
		// System Security is no logner saved, used to validate mail only
		$securityArray = explode(": ",$splitMail[$this->searchPosition]);
		if ($securityArray[0] != "Security") 
		{
			logError("Parser > newParser() function", "System details are invalid");
			return 0;
		}

		// Tempoary Fix for damage taken
		$this->searchPostion ++;
		
		/*
			INVOLVED PARTIES PARSER CODE
		*/
		
		// Reset Counter now we're using segments
		$this->searchPosition = 0;
		$splitMail = explode("\r\n", $this->middleSegment);

		// Process Involved Parties
		$allProcessed = FALSE;
		while ($allProcessed == FALSE)
		{				
			if ($this->searchPosition >= (count($splitMail) - 1))
			{
				$allProcessed = TRUE;
			}
			else
			{
				$checkArray = explode(": ", $splitMail[$this->searchPosition + 1]);
				if ($checkArray[0] == "Security")
				{
					// Have a valid non NPC involved Party
					$killersName = explode(": ", $splitMail[$this->searchPosition]);
					if ($killersName[0] != "Name") 
					{
						logError("Parser > newParser() function", "Involved Party is invalid");
						return 0;
					}

					// Get final blow
					$killersName = explode("(",$killersName[1]);
					$killersName[0] = rtrim($killersName[0]);

					if (isset($killersName[1])) $finalBlow = 1;
					else $finalBlow = 0;

					$killersCorp = explode(": ", $splitMail[$this->searchPosition + 2]);
					if ($killersCorp[0] != "Corp")
					{
						logError("Parser > newParser() function", "Involved Party is invalid");
						return 0;
					}	
					
					$killersAlliance = explode(": ", $splitMail[$this->searchPosition + 3]);
					if ($killersAlliance[0] != "Alliance")
					{
						logError("Parser > newParser() function", "Involved Party is invalid");
						return 0;
					}				
					
					$killersFaction = explode(": ", $splitMail[$this->searchPosition + 4]);
					if ($killersFaction[0] != "Faction")
					{
						logError("Parser > newParser() function", "Involved Party is invalid");
						return 0;
					}

					$killersShip = explode(": ", $splitMail[$this->searchPosition + 5]);
					if ($killersShip[0] != "Ship")
					{
						logError("Parser > newParser() function", "Involved Party is invalid");
						return 0;
					}
										
					$killersWeapon = explode(": ", $splitMail[$this->searchPosition + 6]);
					if ($killersWeapon[0] != "Weapon")
					{
						logError("Parser > newParser() function", "Involved Party is invalid");
						return 0;
					}
										
					$newMail->addInvolved($killersName[0], $killersAlliance[1], $killersFaction[1], $killersCorp[1],
					$killersShip[1], $killersWeapon[1], $finalBlow);
				
					// Skip to Next Involved Party
					$this->searchPosition += 7;
				}
			}
			$this->searchPosition ++;
		}
		
		if (count($newMail->involvedParties) < 1)
		{
			logError("Parser > newParser() function", "No Valid Involved Parties");
			return 0;
		}
		
		/*
			DESTROYED ITEMS PARSER CODE
		*/
		
		// Reset Counter now we're using segments
		$this->searchPosition = 0;
		
		if (isset($this->bottomSegment))
		{
			$splitMail = explode("\r\n", $this->bottomSegment);
			$done = FALSE;
			while ($done == FALSE)
			{
				if ($this->searchPosition >= (count($splitMail) - 1))
				{
					$done = TRUE;
				}
				
				// Get Destroyed Items
				if ($splitMail[$this->searchPosition] != "")
				{
					$itemDetails = explode(" (", $splitMail[$this->searchPosition]);
					if (isset($itemDetails[1]))
					{
						if ($itemDetails[1] == "Cargo)")
						{
							$itemLocation = 2;
						}
						else $itemLocation = 3;
					}
					else $itemLocation = 1;
					
					$itemDetails = explode(", Qty: ", $itemDetails[0]);
					if (isset($itemDetails[1]))
					{
						$itemQuantity = $itemDetails[1];
					}
					else $itemQuantity = 1;
									
					$newMail->addDestroyedItem($itemDetails[0], $itemLocation, $itemQuantity);
				}

				$this->searchPosition ++;

			}
		}
		
		// Everything parsed fine, try to save kill
		$result = $newMail->saveKill();	
						
		if ($result == 1) return 1;
		else 
		{
			logError ("Parser > newParser() function", "Error Saving Kill mail");
			return 0;
		}
		
	}		
}

?>
